package com.springsummer.information.green.webmvc;


import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * request参数映射
 */
public class RequestParameterMapper {

    // 自定义注解，用于指定参数名
    @java.lang.annotation.Target(ElementType.PARAMETER)
    @java.lang.annotation.Retention(RetentionPolicy.RUNTIME)
    public @interface Param {
        String value();
    }

    public Object invokeMethod(Method method, Object target, HttpServletRequest request) throws Exception {
        Parameter[] parameters = method.getParameters();
        Object[] args = new Object[parameters.length];

        for (int i = 0; i < parameters.length; i++) {
            Parameter param = parameters[i];
            String paramName = getParamName(param);
            Class<?> type = param.getType();

            String[] values = request.getParameterValues(paramName);
            args[i] = convertValue(values, type, paramName);
        }

        return method.invoke(target, args);
    }

    public Object[] requestParametersMethodArgsMapping(Method method, HttpServletRequest request) throws Exception {
        Parameter[] parameters = method.getParameters();
        if(parameters==null||parameters.length==0){
            return new Object[0];
        }

        Object[] args = new Object[parameters.length];

        for (int i = 0; i < parameters.length; i++) {
            Parameter param = parameters[i];
            String paramName = getParamName(param);
            Class<?> paramType = param.getType();

            String[] paramValues = request.getParameterValues(paramName);
            args[i] = convertValue(paramValues, paramType, paramName);
        }


        return args;
    }

    private String getParamName(Parameter param) {
        Param annotation = param.getAnnotation(Param.class);
        return annotation != null ? annotation.value() : param.getName();
    }

    private Object convertValue(String[] values, Class<?> targetType, String paramName) throws Exception {
        if (values == null) return handleMissingValue(targetType, paramName);
        if (targetType.isArray()) return handleArray(values, targetType);
        if (Collection.class.isAssignableFrom(targetType)) return handleCollection(values, targetType);
        return convertSingleValue(values[0], targetType, paramName);
    }

    private static Object handleMissingValue(Class<?> type, String paramName) {
        if (type.isPrimitive()) {
            if (int.class == type) return 0;
            if (long.class == type) return 0L;
            if (boolean.class == type) return false;
            // 其他基本类型...
        }
        throw new IllegalArgumentException("Missing required parameter: " + paramName);
    }

    private Object handleArray(String[] values, Class<?> arrayType) {
        Class<?> componentType = arrayType.getComponentType();
        Object array = Array.newInstance(componentType, values.length);
        for (int i = 0; i < values.length; i++) {
            Array.set(array, i, convertSingleValue(values[i], componentType, null));
        }
        return array;
    }

    private Object handleCollection(String[] values, Class<?> collectionType) {
        List<Object> list = new ArrayList<>();
        for (String value : values) {
            list.add(convertSingleValue(value, String.class, null)); // 简化处理泛型类型
        }
        if (collectionType.isInterface()) {
            return Collections.unmodifiableList(list);
        }
        try {
            Collection<Object> collection = (Collection<Object>) collectionType.newInstance();
            collection.addAll(list);
            return collection;
        } catch (Exception e) {
            throw new IllegalArgumentException("Could not instantiate collection type: " + collectionType);
        }
    }

    private Object convertSingleValue(String value, Class<?> targetType, String paramName) {
        try {
            if (targetType == String.class) return value;
            if (targetType == Integer.class || targetType == int.class) return Integer.parseInt(value);
            if (targetType == Long.class || targetType == long.class) return Long.parseLong(value);
            if (targetType == Boolean.class || targetType == boolean.class) return Boolean.parseBoolean(value);
            if (targetType == Date.class) return new SimpleDateFormat("yyyy-MM-dd").parse(value);
            // 添加更多类型转换...
        } catch (Exception e) {
            throw new IllegalArgumentException(
                    "Invalid value '" + value + "' for parameter " + paramName + ": " + e.getMessage()
            );
        }
        throw new IllegalArgumentException("Unsupported parameter type: " + targetType.getName());
    }
}
